/**
 * 深度克隆对象，支持循环引用及多种数据类型
 * @param {Object} obj - 需要克隆的目标对象
 * @param {WeakMap} [hash=new WeakMap()] - 用于存储已克隆对象的哈希表（处理循环引用）
 * @returns {*} 深度克隆后的新对象
 * @throws {Error} 遇到不支持的数据类型时抛出错误
 */
function deepCopy(obj, hash = new WeakMap()) {
  // 处理循环引用
  if (hash.has(obj)) return hash.get(obj);

  // 获取精确类型
  const type = Object.prototype.toString.call(obj);
  
  // 基础类型处理
  if (obj === null || typeof obj !== 'object') return obj;

  // 类型处理器集合
  const handlers = {
    /* Date类型处理：创建新的Date实例保持时间值 */
    '[object Date]': () => new Date(obj.getTime()),
    
    /* RegExp类型处理：复制正则表达式模式和标志 */
    '[object RegExp]': () => new RegExp(obj),
    
    /* Array类型处理：递归克隆数组元素 */
    '[object Array]': () => {
      const copy = [];
      hash.set(obj, copy);
      obj.forEach((item, index) => copy[index] = deepCopy(item, hash));
      return copy;
    },
    
    /* Set类型处理：创建新Set并递归克隆元素 */
    '[object Set]': () => {
      const copy = new Set();
      hash.set(obj, copy);
      obj.forEach(item => copy.add(deepCopy(item, hash)));
      return copy;
    },
    
    /* Map类型处理：创建新Map并递归克隆键值对 */
    '[object Map]': () => {
      const copy = new Map();
      hash.set(obj, copy);
      obj.forEach((value, key) => copy.set(key, deepCopy(value, hash)));
      return copy;
    },
    
    /* Object类型处理：保持原型链的纯对象克隆 */
    '[object Object]': () => {
      const copy = Object.create(Object.getPrototypeOf(obj));
      hash.set(obj, copy);
      for (const key in obj) {
        if (obj.hasOwnProperty(key)) {
          copy[key] = deepCopy(obj[key], hash);
        }
      }
      return copy;
    }
  };

  // 执行类型处理
  if (handlers[type]) {
    return handlers[type]();
  }

  // 不支持的类型
  throw new Error(`Unsupported object type: ${type}`);
}

export const DataUtil = {
  deepCopy,
};
